#ifndef __COPYCAT__
#define __COPYCAT__

#include "ulib.h"
#include "define.h"
#include "tree.h"
#include "giza.h"
#include "rule.h"

class CSent	{
public:
	CUString parse;
	CUStringList src_tok_list;
	CUStringList tgt_tok_list;
	CUStringList align_list;
	int id;

	void Dump( FILE *fp );
};


class COutFiles {
public:
	CUString out_dir;
	CUTextFile file_org_parse;
	CUTextFile file_org_lex;
	CUTextFile file_org_lexpos;
	CUTextFile file_reord_parse;
	CUTextFile file_reord_lex;
	CUTextFile file_reord_lexpos;
	CUTextFile file_reord_copyinfo;

	CUTextFile file_stat;
	CUTextFile file_rules;
	CUTextFile file_rule_cr;
	CUTextFile file_rule_rf;
	CUTextFile file_ins_rule;
	CUTextFile file_src_info;
	bool Prepare( char *arg_dir );
};


class CCopyOpt {
public:
	int depth;
	bool headword;
	bool lexicalized;
	CUString symm;
	bool enable_reorder;
	bool enable_insert;
	bool enable_delete;

	CCopyOpt()	{
		depth=1;
		headword = false;
		lexicalized = false;
		symm = "";

		enable_reorder = false;
		enable_insert = false;
		enable_delete = false;
	}
};


////////////////////////////////////////////////////////////////////////////////////////
class CCopycat {
public:
	CCopycat();
	~CCopycat();

	CSent *sent;
	int num_sent;

	CCopyOpt copyopt;
	CSrcSubTree stree;
	CRuleCross rule_cross; 	// cross reduction method
	CRuleRF rule_rf;		// relative frequency method
	CInsertRule ins_rule;		// insertion rule

	bool LoadCorpus( char *parse_fn, char *giza_fn, char *align_fn );
	bool LoadCorpus( char *parse_fn, char *answer_nao_fn );
	CUString GetSubtreeStr( CTree &t, CNode &n );
	CUString GetSortedSubtreeStr( CTree &t, CNode &n );
	int GetNumCross( CTree &tree, CNode &n, CSent &s );
	void SaveOrg();
	void SaveReord();
	void SaveStat();
	bool SetNodeSpan( CSent &sent, CTree &tree );
	bool TreeInspect( char *parse_fn, char *giza_fn, char *align_fn, char *out_fn );
	bool RuleEval( char *parse_fn, char *answer_nao_fn, char *rf_rule_fn, char *out_fn );
	bool IsAllChildrenAligned( CTree &t, CNode &n );
	double GetAvgAlign( CTree &t, int start );

};



////////////////////////////////////////////////////////////////////////////////////////
class CCopycatTrain : public CCopycat {
public:
	CCopycatTrain()	{
	}

	bool LoadTree( CUString str );

public:
	// training
	bool Train( char *copyopt, char *parse_fn, char *giza_fn, char *align_fn, char *out_fn );
	bool RandReorder();
	bool ExtractSrcSubtree();
	bool ExtractRuleCross();
	bool ExtractRuleRF();
	void RecoverReorder( CNode &r_node, CNode &org_node );
	CUString InsertMissedWords( CTree &t, CNode &n, CSent &s );

	bool ExtractInsRule();

	COutFiles out_files;


private:

};


////////////////////////////////////////////////////////////////////////////////////////
class CCopycatTest : public CCopycat {
public:
	bool LoadRuleCR( char *dir, int cross_red_th );
	bool LoadRuleRF( char *dir, int freq_th, double prob_th );
	bool LoadInsRule( char *dir, int freq_th, double prob_th );
	bool Insert( CTree &t, int &num_reorder, int &num_node, CUString type );
	bool PrintInsertedSent( CTree &t, FILE *tok_fp, FILE *parse_fp, FILE *info_fp );

	bool ApplyRule( char *in_fn, char *tok_fn, char *out_fn, CUString type );
	bool ApplyInsRule( char *in_fn, char *out_fn, CUString type );
	bool ReorderRule( CTree &t, int &num_reorder, int &num_node, CUString type );
	bool PrintReorderedSent( CTree &t, FILE *tok_fp, FILE *parse_fp, FILE *info_fp );
};


#endif
